package weaver.tools.util;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Random;

/**
 * @author dusongsong
 * @date 2024年04月16日 09:45
 */
public class SecretUitl {

    // 加密：传入参数密钥和原始内容的字节信息
    public static byte[] encrypt(byte[] secretKey, byte[] content, byte[] iv) {
        try {
            // 创建密码对象，需要传入算法名称/工作模式/填充方式
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            // 根据secretKey(密钥)的字节内容，"恢复"秘钥对象
            SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
            // CBC模式需要生成一个16 bytes的initialization vector(IV参数 )
            IvParameterSpec ivps = new IvParameterSpec(iv); // 随机数封装成IvParameterSpec参数对象
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);
            // 根据原始内容(字节),进行加密
            byte[] data = cipher.doFinal(content);
            return join(iv, data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 解密：传入参数密钥和机密后内容的字节信息
    public static byte[] decrypt(byte[] secretKey, byte[] input) {
        try {
            // 把input分割成IV和密文
            byte[] iv = new byte[16];
            byte[] data = new byte[input.length - 16];
            System.arraycopy(input, 0, iv, 0, 16);// IV参数
            System.arraycopy(input, 16, data, 0, data.length);// 密文
            System.out.println("IV参数：" + Arrays.toString(iv));// 输出IV参数
            // 创建密码对象，需要传入算法名称/工作模式/填充方式
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            // 根据secretKey(密钥)的字节内容，"恢复"秘钥对象
            SecretKey keySpec = new SecretKeySpec(secretKey, "AES");
            // 回复IV参数
            IvParameterSpec ivps = new IvParameterSpec(iv);
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 数组合并
    public static byte[] join(byte[] arr1, byte[] arr2) {
        byte[] arr = new byte[arr1.length + arr2.length];
        System.arraycopy(arr1, 0, arr, 0, arr1.length);
        System.arraycopy(arr2, 0, arr, arr1.length, arr2.length);
        return arr;
    }

    /**
     * 生成密钥
     */
    public static String geneSHA256Secret(String appCode, String appSecret, long timestamp) {
        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
        return sha256.digestHex(appSecret + ":" + appCode + ":" + timestamp);
    }
    //随机生成四位字母不重复的字符串
    public static String genrateStr(int count) {
        String[] source = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I",
                "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
                "W", "X", "Y", "Z"};
        StringBuilder stringBuilder = new StringBuilder(count);
        int len = source.length;
        for(int i=0;i<count;i++){
            final int index = new Random().nextInt(len);
            stringBuilder.append( source[index] );
        }
        return stringBuilder.toString();
    }

    private static void passwordHashSalt() {
        try {
            String password = "123456";
            String salt = "1abd1c";
            // 创建SHA-256摘要对象
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update((password + salt).getBytes());
            // 计算哈希值
            byte[] result = messageDigest.digest();
            // 将哈希值转换为十六进制字符串
            String hexString = new HexBinaryAdapter().marshal(result);
            System.out.println("Original String: " + password);
            System.out.println("SHA-256 Hash: " + hexString.toLowerCase());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 把字符串IP转换成long
     *
     * @param ipStr 字符串IP
     * @return IP对应的long值
     */
    public static long ip2Long(String ipStr) {
        String[] ip = ipStr.split("\\.");
        return (Long.valueOf(ip[0]) << 24) + (Long.valueOf(ip[1]) << 16)
                + (Long.valueOf(ip[2]) << 8) + Long.valueOf(ip[3]);
    }

    /**
     * 把IP的long值转换成字符串
     *
     * @param ipLong IP的long值
     * @return long值对应的字符串
     */
    public static String long2Ip(long ipLong) {
        StringBuilder ip = new StringBuilder();
        ip.append(ipLong >>> 24).append(".");
        ip.append((ipLong >>> 16) & 0xFF).append(".");
        ip.append((ipLong >>> 8) & 0xFF).append(".");
        ip.append(ipLong & 0xFF);
        return ip.toString();
    }
}
